#include <iostream>
#include <string>
#include <unordered_map>
#include <queue>
using namespace std;

const int N = 8;                                        //总共只有九个字母，控制输入
const string END = "12345678x";                         //判断结束
const int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1}; //偏移方向设置
queue<string> q;                                        //队列，用来装每次拓展的此层的结果
unordered_map<string, int> d;                           //用来记录从初始状态到这里操作了多少部
string state, op;                                       //用来取得初始状态的输入

int bfs(string state) //按照广度优先的方式逐层找到所有可能的状态
{
    q.push(state);
    d[state] = 0;    //将初始状态作为第0层，而且加入队列中
    while (q.size()) //一直循环直到无层可拓展
    {
        string t = q.front();
        q.pop(); //将队头取出，进行拓展下一层操作
        if (t == END)
            return d[t];            //如果队头已经是终点，直接返回
        int dis = d[t];             //记录队头的层数，方便拓展下一层
        int k = t.find('x');        //记录x在字符串的位置，方便二维化
        int x = k % 3, y = k / 3;   //二维化
        for (int i = 0; i < 4; ++i) //上下左右逐层拓展
        {
            int cx = x + dx[i], cy = y + dy[i];
            if (cx >= 0 && cx < 3 && cy >= 0 && cy < 3) //如果此拓展合法
            {
                swap(t[cy * 3 + cx], t[k]); //将此拓展实行
                if (!d.count(t))            //如果此拓展以前没走过，注意，这里的count是指这个字符串在d中出现的次数，但是unordered_map是不允许有重复元素的
                                            //所以这里可以帮理解为出现了没有，虽然d[state]是等于0的，但是d.count(state)也是等于1的
                {
                    q.push(t); //那就作为下一层加入队列
                    d[t] = dis + 1;
                }
                swap(t[cy * 3 + cx], t[k]); //最后记得换回来，向下一层拓展
            }
        }
    }
    return -1; //要是所有层都找不到合适的，那就没有
}

int main()
{
    for (int i = 0; i <= N; ++i) //读入初始状态
    {
        cin >> op;
        state += op[0];
    }
    cout << bfs(state);
    return 0;
}